/**
 * Project Name:java_nio
 * File Name:NClient.java
 * Package Name:com.nclient
 * Date:2016年8月8日下午6:06:00
 * Copyright (c) 2016, chenzhou1025@126.com All Rights Reserved.
 *
*/

package com.alqsoft;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Scanner;

import com.alibaba.fastjson.JSONObject;
import com.alqsoft.bean.BaseInfo;
import com.alqsoft.util.BaseBeanUtils;  
/**
 * ClassName:NClient <br/>
 * Function: TODO ADD FUNCTION. <br/>
 * Reason:	 TODO ADD REASON. <br/>
 * Date:     2016年8月8日 下午6:06:00 <br/>
 * @author   张灿
 * @version  
 * @since    JDK 1.8
 * @see 	 
 */
public class MsClient implements ClientConnectionInterface{
	
    private Selector selector = null;  
    
    private Charset charset = Charset.forName("UTF-8");  
    
    private SocketChannel sc = null; 
    
    public void init(Long accepteId,Long senderId)
    {  
        try {
			selector = Selector.open();
			InetSocketAddress isa = new InetSocketAddress("127.0.0.1",999);  
			sc = SocketChannel.open(isa);  
			sc.configureBlocking(false);  
			sc.register(selector, SelectionKey.OP_READ);  
			new ClientThread().start();  
			Scanner scan = new Scanner(System.in);  
			BaseInfo baseInfo = new BaseInfo();
			BaseBeanUtils.loadBaseInfo(baseInfo);
			sc.write(this.login(senderId,"123456"));
			while (scan.hasNextLine())  
			{  
				String line = scan.nextLine();  
				sc.write(BaseBeanUtils.lengByteBuffer(BaseBeanUtils.integrated(line, accepteId,senderId)));  
			}  
         }catch (IOException e) {
        		e.printStackTrace();
        		System.out.println("连接失败，请检查网络是否正常！");
        } 
    }  
    
    
    @Override
    public ByteBuffer login(Long senderId,String password){
//			sc.write(charset.encode(JSON.toJSONString(BaseBeanUtils.LoginBaseInfo(senderId, password))));
		BaseInfo baseInfo = BaseBeanUtils.LoginBaseInfo(senderId, password);
		ByteBuffer bb = ByteBuffer.allocate(1024);
    	bb.clear();
    	int lenth = BaseBeanUtils.lengSizeInit(baseInfo);
    	bb.limit(4+lenth);
    	bb.putInt(lenth);
    	bb.put(charset.encode(JSONObject.toJSONString(baseInfo)));
    	bb.position(0);
    	return bb;
    }
    
    //定义读取服务器数据的线程  
    private class ClientThread extends Thread  
    {  
        public void run()  
        {  
            try  
            {  
                while (selector.select() > 0)   
                {  
                    //遍历每个有可用IO操作Channel对应的SelectionKey  
                    for (SelectionKey sk : selector.selectedKeys())
                    	
                    {  
                        //删除正在处理的SelectionKey  
                        selector.selectedKeys().remove(sk);  
                        //如果该SelectionKey对应的Channel中有可读的数据  
                        if (sk.isReadable())  
                        {  
                            //使用NIO读取Channel中的数据  
                            SocketChannel sc = (SocketChannel)sk.channel();
                            ByteBuffer intbuff = ByteBuffer.allocate(4);
    						ByteBuffer buff = ByteBuffer.allocate(1024);     //读取OBJ有效数据的缓存池
    					    //有效数据长度  
    					    int ObjLength = 0;  
    					    //从NIO信道中读出的数据长度  
                            String content = "";
//                          字节全部接收完毕
                        	while(sc.read(intbuff)!=0){
//                            	获取报文正常长度
                                ObjLength = intbuff.getInt(0);
                                buff.limit(ObjLength);
    		        		    while(sc.read(buff)!=0){
    		        		    	buff.flip();
    		        		    	content+=charset.decode(buff);
    		        		    }
                               //打印输出读取的内容  
                               System.out.println("聊天信息：" + content);
                            }

                           //为下一次读取作准备  
                           sk.interestOps(SelectionKey.OP_READ);
                        }  
                    }  
                }  
            }  
            catch (IOException ex)  
            {  
                ex.printStackTrace();  
            }  

        }  
    }
}
